package com.common.app.utls.pictureselect

import android.content.Context
import android.net.Uri
import android.view.View
import androidx.media3.common.MediaItem
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView
import com.luck.picture.lib.config.PictureMimeType
import com.luck.picture.lib.config.SelectorConfig
import com.luck.picture.lib.engine.VideoPlayerEngine
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnPlayerListener
import java.io.File
import java.util.concurrent.CopyOnWriteArrayList


/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：23/11/2023
 *
 * 描述：
 *
 * 修订历史：
 *
 */
class ExoPlayerEngine : VideoPlayerEngine<PlayerView> {
    /**
     * 播放状态监听器集
     */
    private val listeners = CopyOnWriteArrayList<OnPlayerListener>()
    override fun onCreateVideoPlayer(context: Context): View {
        val exoPlayer = PlayerView(context)
        exoPlayer.useController = false
        return exoPlayer
    }

    override fun onStarPlayer(exoPlayer: PlayerView, media: LocalMedia) {
        val player = exoPlayer.player
        if (player != null) {
            val mediaItem: MediaItem
            val path = media.availablePath
            mediaItem = if (PictureMimeType.isContent(path)) {
                MediaItem.fromUri(Uri.parse(path))
            } else if (PictureMimeType.isHasHttp(path)) {
                MediaItem.fromUri(path)
            } else {
                MediaItem.fromUri(Uri.fromFile(File(path)))
            }
            val config = SelectorConfig()
            player.repeatMode =
                if (config.isLoopAutoPlay) Player.REPEAT_MODE_ALL else Player.REPEAT_MODE_OFF
            player.setMediaItem(mediaItem)
            player.prepare()
            player.play()
        }
    }

    override fun onResume(exoPlayer: PlayerView) {
        val player = exoPlayer.player
        player?.play()
    }

    override fun onPause(exoPlayer: PlayerView) {
        val player = exoPlayer.player
        player?.pause()
    }

    override fun isPlaying(exoPlayer: PlayerView): Boolean {
        val player = exoPlayer.player
        return player != null && player.isPlaying
    }

    override fun addPlayListener(playerListener: OnPlayerListener) {
        if (!listeners.contains(playerListener)) {
            listeners.add(playerListener)
        }
    }

    override fun removePlayListener(playerListener: OnPlayerListener) {
        if (playerListener != null) {
            listeners.remove(playerListener)
        } else {
            listeners.clear()
        }
    }

    override fun onPlayerAttachedToWindow(exoPlayer: PlayerView) {
        val player: Player = ExoPlayer.Builder(exoPlayer.context).build()
        exoPlayer.player = player
        player.addListener(mPlayerListener)
    }

    override fun onPlayerDetachedFromWindow(exoPlayer: PlayerView) {
        val player = exoPlayer.player
        if (player != null) {
            player.removeListener(mPlayerListener)
            player.release()
            exoPlayer.player = null
        }
    }

    override fun destroy(exoPlayer: PlayerView) {
        val player = exoPlayer.player
        if (player != null) {
            player.removeListener(mPlayerListener)
            player.release()
        }
    }

    /**
     * ExoPlayer播放状态回调
     */
    private val mPlayerListener: Player.Listener = object : Player.Listener {
        override fun onPlayerError(error: PlaybackException) {
            for (i in listeners.indices) {
                val playerListener = listeners[i]
                playerListener.onPlayerError()
            }
        }

        override fun onPlaybackStateChanged(playbackState: Int) {
            if (playbackState == Player.STATE_READY) {
                for (i in listeners.indices) {
                    val playerListener = listeners[i]
                    playerListener.onPlayerReady()
                }
            } else if (playbackState == Player.STATE_BUFFERING) {
                for (i in listeners.indices) {
                    val playerListener = listeners[i]
                    playerListener.onPlayerLoading()
                }
            } else if (playbackState == Player.STATE_ENDED) {
                for (i in listeners.indices) {
                    val playerListener = listeners[i]
                    playerListener.onPlayerEnd()
                }
            }
        }
    }
}